package com.campus.food.security;

import com.campus.food.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;

/**
 * JWT认证过滤器
 * 
 * @author Claude3.7 Sonnet
 * @since 2025-05-29
 */
@Slf4j
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    
    @Autowired
    private JwtUtil jwtUtil;
    
    /**
     * Token请求头名称
     */
    private static final String AUTHORIZATION_HEADER = "Authorization";
    
    /**
     * Token前缀
     */
    private static final String BEARER_PREFIX = "Bearer ";
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, 
                                   FilterChain filterChain) throws ServletException, IOException {
        
        try {
            // 获取JWT Token
            String token = getTokenFromRequest(request);
            
            if (StringUtils.hasText(token) && jwtUtil.validateToken(token)) {
                // 从Token中获取用户信息
                String username = jwtUtil.getUsernameFromToken(token);
                Long userId = jwtUtil.getUserIdFromToken(token);
                Integer role = jwtUtil.getRoleFromToken(token);
                
                // 创建认证对象
                String authority = "ROLE_" + getRoleName(role);
                SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority(authority);
                
                UsernamePasswordAuthenticationToken authentication = 
                    new UsernamePasswordAuthenticationToken(
                        new UserPrincipal(userId, username, role), 
                        null, 
                        Collections.singletonList(grantedAuthority)
                    );
                
                // 设置认证信息到安全上下文
                SecurityContextHolder.getContext().setAuthentication(authentication);
                
                log.debug("JWT认证成功：用户={}, 角色={}", username, authority);
            }
        } catch (Exception e) {
            log.error("JWT认证失败：", e);
            e.printStackTrace();
            // 清除安全上下文
            SecurityContextHolder.clearContext();
        }
        
        // 继续过滤链
        filterChain.doFilter(request, response);
    }
    
    /**
     * 从请求中获取Token
     * 
     * @param request HTTP请求
     * @return JWT Token
     */
    private String getTokenFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader(AUTHORIZATION_HEADER);
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(BEARER_PREFIX)) {
            return bearerToken.substring(BEARER_PREFIX.length());
        }
        return null;
    }
    
    /**
     * 根据角色值获取角色名称
     * 
     * @param role 角色值
     * @return 角色名称
     */
    private String getRoleName(Integer role) {
        switch (role) {
            case 1:
                return "USER";
            case 2:
                return "MERCHANT";
            case 3:
                return "ADMIN";
            default:
                return "USER";
        }
    }
} 